import {polygon2latlngs, sridlocation2laglng, lineString2laglngs, LagLngPoint} from '../zhgeo/LagLng.Utils'
import {ZhgeoIcons} from './zhconfig.js';
import {getServeUrl} from '../../index'
import {latLng2xy, xy2latLng, calcRotateAngle} from '../zhgeo/utils/util'
import {ScenicCronTaskMng} from './cronutils'

const zhgeoIcons = new ZhgeoIcons();
var L = require('../zhgeo/leafletwx')
L.RasterCoords = require('./rastercoords')
require('./qqlayers')
import {createMap} from '../zhgeo/base.map'


function mpoly2Bound(mpoly) {
  let topLeft = new LagLngPoint(mpoly[0].latitude, mpoly[0].longitude);
  let bottomRight = new LagLngPoint(mpoly[0].latitude, mpoly[0].longitude);
  for (let i=1; i<mpoly.length; ++i) {
    topLeft.latitude = Math.min(topLeft.latitude, mpoly[i].latitude);
    topLeft.longitude = Math.min(topLeft.longitude, mpoly[i].longitude);
    bottomRight.latitude = Math.max(bottomRight.latitude, mpoly[i].latitude);
    bottomRight.longitude = Math.max(bottomRight.longitude, mpoly[i].longitude);
  }
  return [topLeft, bottomRight];
}

/**
 * 
 * @param {} cx 中心点
 * @param {} cy 中心点
 * @param {} x 旋转点
 * @param {} y 旋转点
 * @param {} angle 旋转角度，顺时针为正，逆时针为负
 */
function rotate(cx, cy, x, y, angle) {
    var radians = (Math.PI / 180) * angle,
        cos = Math.cos(radians),
        sin = Math.sin(radians),
        nx = (cos * (x - cx)) + (sin * (y - cy)) + cx,
        ny = (cos * (y - cy)) - (sin * (x - cx)) + cy;
    return [nx, ny];
}

function rasterImage2latLng(imgPosition, imgSize, leftUpLatLng, rightDownLatLng) {
  let latLng = new LagLngPoint(0, 0);
  let _imgPos = [
    Math.max(0, Math.max(imgSize[0], imgPosition[0])),
    imgSize[1] - Math.max(0, Math.max(imgSize[1], imgPosition[1])),
  ];
  const ag = xy2latLng(_imgPos[0], _imgPos[1], 0, 0, imgSize[0], imgSize[1], leftUpLatLng.longitude, leftUpLatLng.latitude, rightDownLatLng.longitude, rightDownLatLng.latitude);
  latLng.longitude = ag.lon;
  latLng.latitude = ag.lat;
  return latLng;
}

function latLng2rasterImage(latLng, imgSize, leftUpLatLng, rightDownLatLng) {
  let imgPosition = [0, 0];
  const minLng = Math.min(leftUpLatLng.longitude, rightDownLatLng.longitude);
  const maxLng = Math.max(leftUpLatLng.longitude, rightDownLatLng.longitude);
  const minLat = Math.min(leftUpLatLng.latitude, rightDownLatLng.latitude);
  const maxLat = Math.max(leftUpLatLng.latitude, rightDownLatLng.latitude);
  let lng = Math.min(maxLng, Math.max(latLng.longitude, minLng));
  let lat = Math.min(maxLat, Math.max(latLng.latitude, minLat));

  let xy = latLng2xy(lng, lat, 0, 0, imgSize[0], imgSize[1], leftUpLatLng.longitude, leftUpLatLng.latitude, rightDownLatLng.longitude, rightDownLatLng.latitude)
  return [Math.round(xy.x), Math.round(xy.y)];
}

let id2iconLegend = {};
class IconLegend {
    constructor (data) {
        this.id = null;
        this.name = null;
        this.icon = null;
        this.icon_width = null;
        this.icon_height = null;
        this.init(data);
    }

    init(data) {
      this.id = data["id"];
      this.name = data["name"];
      this.icon = data['icon'] != null ? getServeUrl() + data['icon'] : null;
      this.icon_width = data["icon_width"];
      this.icon_height = data["icon_height"];
    }
}

class Road {
  constructor(data) {
    this.id = null;
    this.name = null;
    this.detail = null;
    this.road_type = null;
    this.route = null;
    this.show_route = true;
    this.contour_color = null
    this.detailLoaded = false;
    this.related_scenics = [];
    this.init(data);
  }
  init(data) {
    this.id = data['id'];
    this.name = data['name'];
    this.related_scenics = data['related_scenics'] ?? []
    this.detail = data['detail'];
    this.road_type = data['road_type'];
    this.route = lineString2laglngs(data["route"]);
    this.show_route = data['show_route'];    
    this.contour_color = data["contour_color"];
  }
}

class RoadType {
  constructor(data) {
    this.id = null;
    this.name = null;
    this.show = null;
    this.roads = [];
    this.init(data);
  }

  init(data) {
    this.id = data['id'];
    this.name = data['name'];
    this.show = data['show'];
    for (let i=0; data["roads"] != null && i< data["roads"].length; ++i) {
      this.roads.push(new Road(data["roads"][i]));
    }
  }
}

class ScenicAreaMap {
  constructor(data) {    
    this.id = null;
    this.name = null;
    this.left_up = null;
    this.right_down = null
    this.zoom = null;
    this.min_zoom = null;
    this.max_zoom = null;
    this.tile_dir = null;
    this.img_height = null;
    this.img_width = null;
    this.rotateAngle = null;    // 旋转角度，顺时针为正，逆时针为负
    this.rotateImgCenter = null;    // 旋转中心，左上角为(0,0)
    this.init(data);
  }

  init(data) {
    this.id = data["id"];
    this.name = data["name"];
    this.left_up = sridlocation2laglng(data['left_up']);
    this.right_down = sridlocation2laglng(data['right_down']);
    this.zoom = data["zoom"];
    this.min_zoom = data["min_zoom"];
    this.max_zoom = data["max_zoom"];
    this.tile_dir = data["tile_dir"];
    this.img_height = data["img_height"];
    this.img_width = data["img_width"];
    this.rotateAngle = calcRotateAngle([this.img_width, this.img_height], this.left_up, this.right_down);
  }
  _rasterImage2LatLng(imgPosition) {
    let imgSize = [this.img_width, this.img_height];
    return rasterImage2latLng(imgPosition, imgSize, this.left_up, this.right_down);
  }

  _latLng2rasterImage(latLng) {
    let imgSize = [this.img_width, this.img_height];
    return latLng2rasterImage(latLng, imgSize, this.left_up, this.right_down);}
}

class ScenicAreaType {
  constructor(data) {
    this.id = null;
    this.name = null;
    this.show = false;
    this.items = [];
    this.requested = false;
    this.init(data);
  }

  init(data) {    
    this.id = data["id"];
    this.name = data["name"];
    this.show = data["show"];
  }
}

class Multimap {
    constructor(data) {
        this.id = null;
        this.name = null;
        this.scenic_area = null;
        this.icon = null;
        this.icon_width = null;
        this.icon_height = null;
        this.orderid = null;
        this.init(data);
    }
    init(data) {
      this.id = data["id"];
      this.name = data["name"];
      this.scenic_area = data["scenic_area"];
      this.icon = data['icon'];
      this.icon_width = data['icon_width'];
      this.icon_height = data['icon_height'];
      this.orderid = data["orderid"];
    }
}

class ScenicArea {
  constructor(data) {
    this.id = null; // 景区id，对应后台系统中的唯一ID
    this.name = null;
    this.show_contour_in_parent = null;
    this.popup_width = null;
    this.detail = null;
    this.location = null;
    this.mpoly = null;
    this.zoom = null;
    this.min_zoom = null;
    this.max_zoom = null;
    this.show_contour = null;
    this.contour_color = null;
    this.cma_color = null;
    this.legend = null;
    this.popup_width = null;
    this.popup_content = null;
    this.show_footer = null;
    this.footerPosition = null;
    this.footer_width = null;
    this.geotiff = null;
    this.geotiff_resolution = null;
    this.scenic_area_type = null;
    this.children_scenic_area_type = [];
    // this.poi = [];
    this.road_type_list = [];
    this.maps = [];
    this.map = null;
    this.rc = null;
    this.mapIndex = -1; // <0为openstreetmap、>=0为this.maps中的对应map
    this.detailLoaded = false;
    this.scenic_area_children_loaded = false;
    this.scenic_area_children = [];
    this.unshow_scenic = {};
    this.audio_file = null;
    this.show_detail = true
    this.show_map = true;
    this.show_nav = true;
    this.show_audio = true;
    this.multimap = [];
    this.cron_task_mng = null;
    this.nearest_show_time = null;
    this.recent_show_time_str = null
    this.recent_show_time = null
    this.today_show_time = null
    this.bound_ratio = null
    this.init(data);
  }

  init(data) {
    this.id = data["id"];
    this.name = data["name"];
    this.show_contour_in_parent = data["show_contour_in_parent"];
    this.popup_width = data['popup_width'];
    this.detail = data["detail"];
    this.location = sridlocation2laglng(data["location"]);
    this.mpoly = polygon2latlngs(data["mpoly"]);
    this.zoom = data["zoom"];
    this.min_zoom = data["min_zoom"];
    this.max_zoom = data["max_zoom"];
    this.show_contour = data["show_contour"];
    this.contour_color = data["contour_color"];
    this.cma_color = data["cma_color"]
    this.legend = data['legend'] == null ? null : id2iconLegend[data['legend']];
    this.popup_width = data['popup_width'];
    this.popup_content = data['popup_content'];
    this.show_footer = data['show_footer'];
    this.footerPosition = data['footer_position'];
    this.footer_width = data['footer_width'];
    this.geotiff = data["geotiff"];
    this.geotiff_resolution = data["geotiff_resolution"];
    this.scenic_area_type = data["scenic_area_type"];
    this.bound_ratio = data["bound_ratio"] ?? 1
    this.children_scenic_area_type = []
    for (let i=0; data["children_scenic_area_type"] != null && i< data["children_scenic_area_type"].length; ++i) {
      this.children_scenic_area_type.push(new ScenicAreaType(data["children_scenic_area_type"][i]));
    }
    this.unshow_scenic = {};
    // this.poi = []
    // for (let i=0; data["poi"] != null && i<data["poi"].length; ++i) {
    //   this.poi.push(new CommonPoiType(data["poi"][i]));
    // }
    this.road_type_list = []
    for (let i=0; data["road_type_list"] != null && i<data["road_type_list"].length; ++i) {
      this.road_type_list.push(new RoadType(data["road_type_list"][i]));
    }
    this.maps = []
    for (let i=0; data["maps"] != null && i<data["maps"].length; ++i) {
      this.maps.push(new ScenicAreaMap(data["maps"][i]));
    }    
    this.audio_file = data['audio_file'] != null ? getServeUrl() + data['audio_file'] : null;
    this.show_detail = data['show_detail'] ?? true;
    this.show_map = data['show_map'] ?? true;
    this.show_nav = data['show_nav'] ?? true;
    this.show_audio = data['show_audio'] ?? true;
    this.multimap = []
    for (let i=0; data["multimap"] != null && i<data["multimap"].length; ++i) {
      this.multimap.push(new Multimap(data["multimap"][i]));
    }
  }

  createMap(page, contanter, callback) {
    let that = this;
    that.page = page;
    if (that.maps.length > 0) {
        that.mapIndex = 0;
    }
    if (that.mapIndex >= 0) {
        let smap = that.maps[that.mapIndex];
        createMap(contanter, {
            crs: L.CRS.Simple,
            minZoom: smap.min_zoom,
            maxZoom: smap.max_zoom,
            preferCanvas: true,
            }, (_map)=>{
                that.map = _map
                let img = [
                    smap.img_width, // original width of image
                    smap.img_height  // original height of image
                    ];
                that.rc = new L.RasterCoords(that.map, img);
                that.compassRotateAngle = -smap.rotateAngle
                if (callback != null) callback();
            })
    } else {
        createMap(contanter, {preferCanvas: true,}, (_map)=> {
            that.map = _map
            if (callback != null) callback();
        })
    }
  }

  initTileLayer() {
    var that = this;
    if (that.mapIndex >= 0) {
      let smap = that.maps[that.mapIndex];
      that.map.setView(that.rc.unproject([smap.img_width / 2, smap.img_height / 2]), smap.zoom);
      L.tileLayer(getServeUrl() + smap.tile_dir + '/{z}/{x}/{y}.png', {
        noWrap: true,
        bounds: that.rc.getMaxBounds(),
        // maxNativeZoom: that.rc.zoomLevel()
      }).addTo(that.map)
    } else {
      var Normal = L.tileLayer.txMapTileLayer("Normal", {
        minNativeZoom: 3,
        maxNativeZoom: 18,
        minZoom: that.min_zoom,
        maxZoom: that.max_zoom,
      }); //调用 腾讯地图
      Normal.addTo(that.map)
      that.map.setView(that.location.toArray(), that.zoom);
      // 计算bound
      if (that.mpoly.length >= 2) {
        let latLngBound = mpoly2Bound(that.mpoly);
        var corner1 = L.latLng(
            that.location.latitude - that.bound_ratio * Math.abs(latLngBound[0].latitude - that.location.latitude),
            that.location.longitude - that.bound_ratio * Math.abs(latLngBound[0].longitude - that.location.longitude)
        ),
        corner2 = L.latLng(
            that.location.latitude + that.bound_ratio * Math.abs(latLngBound[1].latitude - that.location.latitude), 
            that.location.longitude + that.bound_ratio * Math.abs(latLngBound[1].longitude - that.location.longitude)
        ),
        bounds = L.latLngBounds(corner1, corner2);
        that.map.setMaxBounds(bounds);
      }
    }
  }

  showAreaContour() {
    var that = this
    if (that.mpoly != null && that.show_contour != null && that.show_contour) {
        that.showPolygon(that, 8);
    }
  }

  initPois() {
    let that = this;
    global.wxRequest.getIconLegendList(that.id, function (legends) {
        for (let i=0; i<legends.length; ++i) {
            id2iconLegend[legends[i].id] = legends[i];
        }
        let showTypeList = []
        for (let i=0; i<that.children_scenic_area_type.length; ++i) {
            if (that.children_scenic_area_type[i].show) {
                showTypeList.push(i)
            }
        }
        for (let i=0; i<showTypeList.length; ++i) {
            that.showPois(that.children_scenic_area_type[showTypeList[i]], i==showTypeList.length-1)
        }
        // for (let i=0; i<that.poi.length; ++i) {
        //   if (that.poi[i].show) {
        //     that.showPois(that.poi[i]);
        //     showed = true;
        //   }
        // }
        if (showTypeList.length == 0 && that.cron_task_mng == null) {
            that.cron_task_mng = new ScenicCronTaskMng()
            that.cron_task_mng.init(that);
        }
    })
  }

  showPois(poiType, initLastType) {
    let that = this;
    if (poiType.requested) {
        for (let i=0; i<poiType.items.length; ++i) {
          that.showPoi(poiType.items[i]);
        }
    } else {
        global.wxRequest.getScenicAreaChildren(this.id, poiType.id, function(items) {
            let id2item = {}
            for (let i=0; i<poiType.items.length; ++i) {
                id2item[poiType.items[i].id] = poiType.items[i]
            }
            for (let i=0; i<items.length; ++i) {
                if (id2item.hasOwnProperty(items[i].id)) {
                    continue;
                } else {
                    poiType.items.push(items[i]);
                }
            }
            // poiType.items = items;
            poiType.requested = true;
            for (let i=0; i<poiType.items.length; ++i) {
                that.showPoi(poiType.items[i]);
            }
            if (initLastType && that.cron_task_mng == null) {
                that.cron_task_mng = new ScenicCronTaskMng()
                that.cron_task_mng.init(that);
            }
        });  
    }
  }

  showPoi(poi) {
    var that = this;
    poi.marker_times ??= 0
    if (poi.marker_leaflet_id != null) {
        that.map.removeLayer( L.id2obj[poi.marker_leaflet_id] );
        poi.marker_leaflet_id = null
    }
    let m;
    if (that.mapIndex >= 0) {
      let smap = that.maps[that.mapIndex];
      m = L.marker(that.rc.unproject(smap._latLng2rasterImage(poi.location)), {
        src: poi.legend == null ? null : poi.legend.icon,
        width: poi.legend == null ? poi.footer_width : poi.legend.icon_width,
        height: poi.legend == null ? 26 : poi.legend.icon_height,
        title: poi.name,
        showFooter: poi.show_footer,
        footerWidth: poi.footer_width,
        footerPosition: poi.footerPosition,
        left_badge: poi.left_badge,
        right_badge: poi.right_badge,
        showInCenter: true,
      }).addTo(that.map);
    } else {
      m = L.marker(poi.location.toArray(), {
        src: poi.legend == null ? null : poi.legend.icon,
        width: poi.legend == null ? poi.footer_width : poi.legend.icon_width,
        height: poi.legend == null ? 26 : poi.legend.icon_height,
        title: poi.name,
        showFooter: poi.show_footer,
        footerWidth: poi.footer_width,
        footerPosition: poi.footerPosition,
        left_badge: poi.left_badge,
        right_badge: poi.right_badge,
        showInCenter: true,
      }).addTo(that.map);
    }
    poi.marker_leaflet_id = m._leaflet_id;
    poi.marker_times += 1
    if (poi.popup_content != null && poi.popup_content != "") {
      m.bindPopup(poi.popup_content, {
          width: poi.popup_width
        });
    }
    m.poi = poi;
    if (poi.mpoly != null && poi.show_contour_in_parent != null && poi.show_contour_in_parent) {
        that.showPolygon(poi);
    }
    m.on({
        click: that.clickPoi
    }, that.page)
  }

  hidePoi(poi) {
    var that = this;
    if (poi.marker_leaflet_id != null) {
        that.map.removeLayer( L.id2obj[poi.marker_leaflet_id] );
    }
    poi.marker_leaflet_id = null;

    let hasPoly = false;
    if (poi.polyline_leaflet_id != null) {
        that.map.removeLayer( L.id2obj[poi.polyline_leaflet_id] );
        poi.polyline_leaflet_id = null;
        hasPoly = true;
    }
    if (poi.marker_times != null) {
        poi.marker_times -= 1
        if (poi.marker_times > 0) {
            poi.marker_times -= 1
            that.showPoi(poi)
            if (hasPoly) {
                that.showPolygon(poi)
            }
        }
    }
  }

  hidePois(poiType) {
    let that = this;
    if (poiType.requested) {
        for (let i=0; i<poiType.items.length; ++i) {
          if (poiType.items[i].marker_leaflet_id != null) {
            that.hidePoi(poiType.items[i])
          }
        }
    }
  }

  clickPoi(e) {
    let marker = e.target;
    let that = this;
    if (marker._popup == null) {
        if (marker.poi.show_detail) {
            that.showPoiDetailHalfScreen(marker.poi);
        }
    } else {
        marker.togglePopup();
        if (marker.isPopupOpen() && marker.poi.show_detail) {
            that.showPoiDetailHalfScreen(marker.poi);
        }
    }
  }

  showPolygon(obj, weight) {
    let that = this;
    let polygon = obj.mpoly
    if(polygon == null || polygon.length < 2) return;
    
    if (obj.polyline_leaflet_id != null) {
        that.map.removeLayer( L.id2obj[obj.polyline_leaflet_id] );
        obj.polyline_leaflet_id = null
    }

    let mpoly = [];    
    if (that.mapIndex >= 0) {
        let smap = that.maps[that.mapIndex];
        for (let i=0; i<polygon.length; ++i) {
            mpoly.push(that.rc.unproject(smap._latLng2rasterImage(polygon[i])));
        }
    } else {
        for (let i=0; i<polygon.length; ++i) {
            mpoly.push(polygon[i].toArray());
        }
    }
    let l = L.polyline(mpoly, {color: obj.contour_color, weight: weight??4}).addTo(that.map);
    obj.polyline_leaflet_id = l._leaflet_id;
  }

  hidePolygon(obj) {
    let that = this
    if (obj.polyline_leaflet_id != null) {
        that.map.removeLayer( L.id2obj[obj.polyline_leaflet_id] );
        obj.polyline_leaflet_id = null;
    }
  }

  showLine(obj, line, weight) {
    let that = this;
    if(line == null || line.length < 2) return;
    let mpoly = [];
    
    if (that.mapIndex >= 0) {
        let smap = that.maps[that.mapIndex];
        for (let i=0; i<line.length; ++i) {
            mpoly.push(that.rc.unproject(smap._latLng2rasterImage(line[i])));
        }
    } else {
        for (let i=0; i<line.length; ++i) {
            mpoly.push(line[i].toArray());
        }
    }
    let l = L.polyline(mpoly, {color: obj.contour_color, weight: weight??3}).addTo(that.map);
    obj.line_leaflet_id = l._leaflet_id;
  }

  hideLine(obj) {
    let that = this
    if (obj.line_leaflet_id != null) {
        that.map.removeLayer( L.id2obj[obj.line_leaflet_id] );
        obj.line_leaflet_id = null;
    }   
  }

  showLocation() {
    let that = this;
    wx.getLocation({
      type: 'gcj02',
      isHighAccuracy: true,
      success (res) {
        const latitude = res.latitude;
        const longitude = res.longitude;
        const speed = res.speed;
        const accuracy = res.accuracy;
        
        let coords;
        if (that.mapIndex >= 0) {
            let smap = that.maps[that.mapIndex];
            coords = that.rc.unproject(smap._latLng2rasterImage(new LagLngPoint(latitude, longitude)))
        } else {
            coords = [latitude, longitude];
        }
        that.location_coords = coords;
        that.map.setView(coords);

        if (that.locatio_marker_leaflet_id == null) {
            let m = L.marker(coords, {
                src: zhgeoIcons.locationNow,
                width: 32,
                height: 32,
                showInCenter: false,
            }).addTo(that.map);
            that.locatio_marker_leaflet_id = m._leaflet_id;
        } else {
            L.id2obj[that.locatio_marker_leaflet_id].setLatLng(coords);
        }
            // that.map.removeLayer( L.id2obj[poiType.items[i].marker_leaflet_id] );
      },
      fail (res) {
        console.log(res);
        if (that.location_coords == null) return;
        that.map.setView(that.location_coords);
      }
    });
  }

  showRoadDirect (road) {
    let that = this;
    let id2children = {};
    let id2type = {};
    for (let t=0; t<that.children_scenic_area_type.length; ++t) {
        id2type[that.children_scenic_area_type[t].id] = that.children_scenic_area_type[t]
        for (let s=0; s<that.children_scenic_area_type[t].items.length; ++s) {
            let item = that.children_scenic_area_type[t].items[s]
            id2children[item.id] = item;
        }
    }
    for (let sid in that.unshow_scenic) {
        if (!id2children.hasOwnProperty(sid)) {
            id2children[sid] = that.unshow_scenic[sid]
        }
    }
    for (let i=0; i<road.related_scenics.length; ++i) {
        if (id2children.hasOwnProperty(road.related_scenics[i])) {
            let poi = id2children[road.related_scenics[i]]
            poi.left_badge = i + 1;
            that.showPoi(poi);
        }
    }
    if (road.show_route) {
        that.showLine(road, road.route)
    }
  }

  showRoad (road) {
    let that = this
    that.roadShowing = road;
    let id2children = {};
    let id2type = {};
    for (let t=0; t<that.children_scenic_area_type.length; ++t) {
        id2type[that.children_scenic_area_type[t].id] = that.children_scenic_area_type[t]
        for (let s=0; s<that.children_scenic_area_type[t].items.length; ++s) {
            let item = that.children_scenic_area_type[t].items[s]
            id2children[item.id] = item;
        }
    }
    for (let sid in that.unshow_scenic) {
        if (!id2children.hasOwnProperty(sid)) {
            id2children[sid] = that.unshow_scenic[sid]
        }
    }
    let unloaded = []
    for (let i=0; i<road.related_scenics.length; ++i) {
        if (!id2children.hasOwnProperty(road.related_scenics[i])) {
            unloaded.push(road.related_scenics[i])
        }
    }

    if (unloaded.length == 0) {
        that.showRoadDirect(road)
    } else {
        global.wxRequest.postScenicList(unloaded, function(data) {
            for (let i=0; i<data.length; ++i) {
                let scenic = new ScenicArea(data[i])
                if (id2children.hasOwnProperty(scenic.id)) {
                    continue
                }
                if (!id2type.hasOwnProperty(scenic.scenic_area_type)) {
                    that.unshow_scenic[scenic.id] = scenic;
                } else {
                    id2type[scenic.scenic_area_type].items.push(scenic)
                }
            } 
            that.showRoadDirect(road)
        })
    }
  }

  hideRoad (road) {
    let that = this;
    let id2children = {};
    let id2type = {};
    for (let t=0; t<that.children_scenic_area_type.length; ++t) {
        id2type[that.children_scenic_area_type[t].id] = that.children_scenic_area_type[t]
        for (let s=0; s<that.children_scenic_area_type[t].items.length; ++s) {
            let item = that.children_scenic_area_type[t].items[s]
            id2children[item.id] = item;
        }
    }
    for (let sid in that.unshow_scenic) {
        if (!id2children.hasOwnProperty(sid)) {
            id2children[sid] = that.unshow_scenic[sid]
        }
    }
    for (let i=0; i<road.related_scenics.length; ++i) {
        if (id2children.hasOwnProperty(road.related_scenics[i])) {
            let poi = id2children[road.related_scenics[i]]
            poi.left_badge = null;
            that.hidePoi(poi);
        }
    }
    that.roadShowing = null;
    if (road.show_route) {
        that.hideLine(road)
    }
  }
}

class Track {
  constructor() {
    this.id = null;
  }
}

export {IconLegend, RoadType, Road, ScenicAreaMap, ScenicArea, Track}